package rock.registry.zk;

import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;
import rock.common.enums.RpcErrorMessageEnum;
import rock.common.extension.ExtensionLoader;
import rock.exception.RpcException;
import rock.loadbalance.LoadBalance;
import rock.registry.ServiceDiscovery;
import rock.registry.zk.util.ZkCuratorUtil;
import rock.remoting.dto.RpcRequest;

import java.net.InetSocketAddress;
import java.util.List;

@Slf4j
public class ZkServiceDiscoveryImpl implements ServiceDiscovery {

    // 负载均衡
    private final LoadBalance loadBalance;

    public ZkServiceDiscoveryImpl() {
        this.loadBalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension("loadBalance");
    }

    @Override
    public InetSocketAddress lookup(RpcRequest request) {
        String rpcServiceName = request.getRpcServiceName();
        CuratorFramework zkClient = ZkCuratorUtil.getZkClient();

        List<String> serviceUrlList = ZkCuratorUtil.getChildrenNodes(zkClient, rpcServiceName);
        if (null == serviceUrlList || serviceUrlList.isEmpty()) {
            throw new RpcException(RpcErrorMessageEnum.SERVICE_CAN_NOT_BE_FOUND, rpcServiceName);
        }

        log.debug("available services: [{}], request: [{}]", serviceUrlList, request);
        // 服务发现：通过负载均衡实现，本质是从众多可服务的节点中选一个
        String targetServiceUrl = loadBalance.selectServiceAddress(serviceUrlList, request);
        log.info("found service success: [{}]", targetServiceUrl);

        String[] socketAddressArr = targetServiceUrl.split(":", 2);
        String host = socketAddressArr[0];
        int port = Integer.parseInt(socketAddressArr[1]);

        return new InetSocketAddress(host, port);
    }
}
